home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / glibc108.zip / glibc108 / sysdeps / unix / sysv / sysv4 / __waitpid.c < prev    next >
C/C++ Source or Header  |  1994-01-26  |  4KB  |  119 lines

  1. /* Copyright (C) 1993, 1994 Free Software Foundation, Inc.
  2.    Contributed by Brendan Kehoe (brendan@zen.org).
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ansidecl.h>
  20. #include <errno.h>
  21. #include <sys/wait.h>
  22. #include <sys/types.h>
  23. #include <stddef.h>
  24. #include "siginfo.h"
  25.  
  26. typedef enum __idtype
  27.   {
  28.     /* Look for processes based upon a given PID.  */
  29.     P_PID,
  30.  
  31.     /* Look for processes based upon a given process-group ID.  */
  32.     P_PGID = 2,
  33.  
  34.     /* Look for any process.  */
  35.     P_ALL = 7,
  36.   } __idtype_t;
  37.  
  38. extern __pid_t __getpgid __P ((__pid_t pid));
  39. extern int __waitid __P ((__idtype_t idtype, __pid_t id,
  40.               __siginfo_t *infop, int options));
  41.  
  42. /* Wait for a child matching PID to die.
  43.    If PID is greater than 0, match any process whose process ID is PID.
  44.    If PID is (pid_t) -1, match any process.
  45.    If PID is (pid_t) 0, match any process with the
  46.    same process group as the current process.
  47.    If PID is less than -1, match any process whose
  48.    process group is the absolute value of PID.
  49.    If the WNOHANG bit is set in OPTIONS, and that child
  50.    is not already dead, return (pid_t) 0.  If successful,
  51.    return PID and store the dead child's status in STAT_LOC.
  52.    Return (pid_t) -1 for errors.  If the WUNTRACED bit is set in OPTIONS,
  53.    return status for stopped children; otherwise don't.  */
  54.  
  55. __pid_t
  56. DEFUN(__waitpid, (pid, stat_loc, options),
  57.       __pid_t pid AND int *stat_loc AND int options)
  58. {
  59.   __idtype_t idtype;
  60.   __pid_t tmp_pid = pid;
  61.   __siginfo_t infop;
  62.  
  63.   if (pid <= WAIT_MYPGRP)
  64.     {
  65.       if (pid == WAIT_ANY)
  66.     {
  67.       /* Request the status for any child.  */
  68.       idtype = P_ALL;
  69.     }
  70.       else if (pid == WAIT_MYPGRP)
  71.     {
  72.       /* Request the status for any child process that has
  73.          a pgid that's equal to that of our parent.  */
  74.       tmp_pid = __getpgid (0);
  75.       idtype = P_PGID;
  76.     }
  77.       else /* PID < -1 */
  78.     {
  79.       /* Request the status for any child whose pgid is equal
  80.          to the absolute value of PID.  */
  81.       tmp_pid = pid & ~0; /* XXX not pseudo-insn */
  82.       idtype = P_PGID;
  83.     }
  84.     }
  85.   else
  86.     {
  87.       /* Request the status for the child whose pid is PID.  */
  88.       idtype = P_PID;
  89.     }
  90.  
  91.   if (__waitid (idtype, tmp_pid, &infop, options | WEXITED | WTRAPPED) < 0)
  92.     return -1;
  93.  
  94.   switch (infop.__code)
  95.     {
  96.     case EXITED:
  97.       *stat_loc = W_EXITCODE (infop.__status, 0);
  98.       break;
  99.     case STOPPED:
  100.     case TRAPPED:
  101.       *stat_loc = W_STOPCODE (infop.__status);
  102.       break;
  103.     case KILLED:
  104.       /* Don't know what to do with continue, since it isn't documented.
  105.      Putting it here seemed the right place though. */
  106.     case CONTINUED:
  107.       *stat_loc = infop.__status;
  108.       /* FALLTHROUGH */
  109.     case CORED:
  110.       *stat_loc |= WCOREFLAG;
  111.       break;
  112.     }
  113.  
  114.   /* Return the PID out of the INFOP structure instead of the one we were
  115.      called with, to account for cases of being called with -1 to signify
  116.      any PID.  */
  117.   return infop.__pid;
  118. }
  119.